//-----------------------------------------------------------------------
// <copyright file="GetLatest.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Ben Lilley</author>
// <email>benjililley@hotmail.com</email>
// <date>2007-07-23</date>
// <summary>Performs a GET against a Sourcegear Vault server.</summary>
//-----------------------------------------------------------------------
namespace Microsoft.Sdc.Tasks.Vault
{
    using System;
    using Microsoft.Sdc.Tasks.Configuration;
    using Microsoft.Build.Framework;

    /// <summary>
    /// Performs a GET from the Sourcegear Vault server specified.  The latest version is retrieved.
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[
    /// <Vault.GetLatest
    ///         Server="server" 
    ///         Repository="repository"
    ///         Username="username"
    ///         Password="password"
    ///         DestinationDirectory="destinationPath"
    ///         ItemPath="itemPath"
    ///         VaultClientPath="clientExePath"
    ///         UseSSL="useSSL"
    /// />
    /// ]]></code>
    /// <para>where:</para>
    /// <para><i>server</i></para>
    /// <para>The IP address or hostname of the Vault server to connect to.</para>
    /// <para><i>username</i></para>
    /// <para>The Vault username.</para>
    /// <para><i>password</i></para>
    /// <para>The password for the username specified in <i>username</i></para>
    /// <para><i>destinationPath</i></para>
    /// <para>The full path to download repository files to.</para>
    /// <para><i>itemPath</i></para>
    /// <para>The full repository path to the item to perform the get operation on.</para>
    /// <para><i>clientExePath</i></para>
    /// <para>Optional - the path to vault.exe.  If the Vault registry keys exist or the path to vault.exe is set in your enviroment path, this does not need to be used.</para>
    /// <para><i>useSSL</i></para>
    /// <para>Optional (default False) - if set SSL will be used to communicate with the Vault server.  If enabled the Vault server specified in <i>server</i> must support SSL.</para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <Vault.GetLatest
    ///                 Server="192.168.1.100" 
    ///                 Repository="MyCode"
    ///                 Username="username"
    ///                 Password="password"
    ///                 DestinationDirectory="c:\ItemSource"
    ///                 ItemPath="$/Repos/Item"
    ///         />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class GetLatest : TaskBase
    {
        private string server;
        private string repository;
        private string itemPath;
        private string destinationDirectory;
        private string username;
        private string password;
        private string vaultClientPath;
        private bool useSSL = false;

        /// <summary>
        /// Gets or sets the server.
        /// </summary>
        /// <value>The server.</value>
        [Required]
        public string Server
        {
            get { return (this.server ?? String.Empty); }
            set { this.server = value; }
        }

        /// <summary>
        /// Gets or sets the repository.
        /// </summary>
        /// <value>The repository.</value>
        [Required]
        public string Repository
        {
            get { return (this.repository ?? String.Empty); }
            set { this.repository = value; }
        }

        /// <summary>
        /// Gets or sets the item path.
        /// </summary>
        /// <value>The item path.</value>
        [Required]
        public string ItemPath
        {
            get { return (this.itemPath ?? String.Empty); }
            set { this.itemPath = value; }
        }

        /// <summary>
        /// Gets or sets the destination directory.
        /// </summary>
        /// <value>The destination directory.</value>
        [Required]
        public string DestinationDirectory
        {
            get { return (this.destinationDirectory ?? String.Empty); }
            set { this.destinationDirectory = value; }
        }

        /// <summary>
        /// Gets or sets the username.
        /// </summary>
        /// <value>The username.</value>
        [Required]
        public string Username
        {
            get { return (this.username ?? String.Empty); }
            set { this.username = value; }
        }

        /// <summary>
        /// Gets or sets the password.
        /// </summary>
        /// <value>The password.</value>
        [Required]
        public string Password
        {
            get { return (this.password ?? String.Empty); }
            set { this.password = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [use SSL].
        /// </summary>
        /// <value><c>true</c> if [use SSL]; otherwise, <c>false</c>.</value>
        public bool UseSSL
        {
            get { return this.useSSL; }
            set { this.useSSL = value; }
        }

        /// <summary>
        /// Gets or sets the vault client path.
        /// </summary>
        /// <value>The vault client path.</value>
        public string VaultClientPath
        {
            get { return (this.vaultClientPath ?? String.Empty); }
            set { this.vaultClientPath = value; }
        }

        /// <summary>
        /// This is the main execute method that all tasks should implement
        /// </summary>
        protected override void InternalExecute()
        {
            if (String.IsNullOrEmpty(this.VaultClientPath))
            {
                this.VaultClientPath = VaultUtil.GetVaultExePath("vault.exe");
            }

            ShellExecute shell = new ShellExecute();
            shell.Filename = this.VaultClientPath;

            this.VaultGetLatest(shell);
        }

        /// <summary>
        /// Gets the latest.
        /// </summary>
        /// <param name="shell">The shell.</param>
        private void VaultGetLatest(ShellExecute shell)
        {
            /*********************************/
            /*** determine get to location ***/

            string getLocation = VaultUtil.CreateGetToPath(this.DestinationDirectory);

            /*************************************/
            /*** create options for get latest ***/
            GetOpts opts = new GetOpts(this.Server, this.Repository, this.ItemPath, getLocation, this.Username, this.Password, null, this.UseSSL);
            
            /*************************************/
            /*** execute the get against vault ***/

            Log.LogMessageFromResources(MessageImportance.Normal, "Vault.GetLatest", this.ItemPath);
            Result vaultResult = VaultUtil.Get(opts, shell);

            if (!vaultResult.Success)
            {
                Log.LogMessageFromResources(MessageImportance.High, "Vault.Error");
                throw new TaskException("Vault.Exception", vaultResult.Exception);
            }
        }
    }
}